#include "xml_io.h"

#include <map>
#include <fstream>
//
#include "strchange.h"
#include "File.h"
#include "Log.h"

#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"


void read_AliyunConf(acl::xml_node* pnode,acl::xml_node* pchild,pyfree::AliyunTriples &aliconf)
{
	while (pchild){
		//
		if (0==strcmp("product_key",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.product_key = std::string(val_);
		}
		if (0==strcmp("product_secret",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.product_secret = std::string(val_);
		}
		if (0==strcmp("device_name",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.device_name = std::string(val_);
		}
		if (0==strcmp("device_secret",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.device_secret = std::string(val_);
		}
		pchild = pnode->next_child();
	}
	Print_NOTICE("\nAliyunConf:\nproduct_key:%s\nproduct_secret:%s\ndevice_name:%s\ndevice_secret:%s\r\n"
		,aliconf.product_key.c_str()
		,aliconf.product_secret.c_str()
		,aliconf.device_name.c_str()
		,aliconf.device_secret.c_str());
}

void read_AliyunOTAConf(acl::xml_node* pnode,acl::xml_node* pchild,pyfree::OTAAliyun &aliconf)
{
	while (pchild){
		//
		if (0==strcmp("version_file",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.version_file = std::string(val_);
		}
		if (0==strcmp("update_file",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.update_file = std::string(val_);
		}
		if (0==strcmp("zip_path",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.zip_path = std::string(val_);
		}
		if (0==strcmp("update_dir",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				aliconf.update_dir = std::string(val_);
		}
		pchild = pnode->next_child();
	}
	Print_NOTICE("\nAliyunOTAConf:\nversion_file:%s\nupdate_file:%s\nzip_path:%s\nupdate_dir:%s\r\n"
		,aliconf.version_file.c_str()
		,aliconf.update_file.c_str()
		,aliconf.zip_path.c_str()
		,aliconf.update_dir.c_str());
}

void read_WebConf(acl::xml_node* pnode,acl::xml_node* pchild,pyfree::WebConf &webconf)
{
	while (pchild){
		//
		if (0==strcmp("ip",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				webconf.ip = std::string(val_);
		}
		if (0==strcmp("port",pchild->tag_name())) 
		{
			const char* val_ = pchild->text();
			if (strlen(val_)>0)
				webconf.port = atoi(val_);
		}
		pchild = pnode->next_child();
	}
	Print_NOTICE("\nWebConf:\nip:%s\nport:%d\r\n"
		,webconf.ip .c_str()
		,webconf.port);
}


void pyfree::readAppConf(ServiceConf &conf, std::string xml_)
{
	try
	{
        acl::string buf;
		if (acl::ifstream::load(xml_.c_str(), &buf) == false)
		{
			Print_WARN("load %s error %s\r\n", xml_.c_str(), acl::last_serror());
			return;
		}

		acl::xml1 xml;
		xml.update(buf);

		acl::xml_node* node 	= &(xml.get_root());
		acl::xml_node* child 	= node->first_child();
        while (child)
		{
			if(0==strcmp(child->tag_name(), "appconf"))
			{
				node	= child;
				child 	= node->first_child();
				while (child)
				{
					if (0==strcmp("aliyunfunc",child->tag_name())) 
					{
						const char* val_ = child->text();
						if (strlen(val_)>0)
							conf.aliyunfunc = atoi(val_)>0?true:false;
					}
					if (0==strcmp("AliyunConf",child->tag_name())) 
					{
						acl::xml_node* pnode 	= child;
						acl::xml_node* pchild 	= pnode->first_child();
						read_AliyunConf(pnode,pchild,conf.gateway);
					}
					if (0==strcmp("svc_def_path",child->tag_name())) 
					{
						const char* val_ = child->text();
						if (strlen(val_)>0)
							conf.svcdefine = std::string(val_);
					}
					if (0==strcmp("AliyunOTAConf",child->tag_name())) 
					{
						acl::xml_node* pnode 	= child;
						acl::xml_node* pchild 	= pnode->first_child();
						read_AliyunOTAConf(pnode,pchild,conf.otaInfo);
					}
					if (0==strcmp("webfunc",child->tag_name())) 
					{
						const char* val_ = child->text();
						if (strlen(val_)>0)
							conf.webfunc = atoi(val_)>0?true:false;
					}
					if (0==strcmp("web_conf",child->tag_name())) 
					{
						acl::xml_node* pnode 	= child;
						acl::xml_node* pchild 	= pnode->first_child();
						read_WebConf(pnode,pchild,conf.webconf);
					}
					child = node->next_child();
				}
				break;
			}
			child = node->next_child();
		}
		CLogger::createInstance()->Log(MsgInfo,"success for read %s!\n",xml_.c_str());
	}catch (...)
	{
		CLogger::createInstance()->Log(MsgError,
			"read xml file[%s] error: %s %s %d,please check the file format and code!\n"
			, xml_.c_str(), __FILE__, __FUNCTION__, __LINE__);
	}
};

void pyfree::writeAppConf(const ServiceConf conf, std::string xml_)
{
	try {
	}
	catch (...)
	{
		CLogger::createInstance()->Log(MsgError
			, "write xml file[%s] error[%s]: %s %s %d"
			", please check the code!"
			, xml_.c_str()
			, __FILE__, __FUNCTION__, __LINE__);
	}
};

//get node attr
static void getAtt(const acl::xml_node* node,std::map<std::string,std::string> &atts_)
{
	const acl::xml_attr* attr = node->first_attr();
	while (attr)
	{
		std::map<std::string,std::string>::iterator it = atts_.find(std::string(attr->get_name()));
		if(it != atts_.end())
		{
			it->second = std::string(attr->get_value());
		}
		attr = node->next_attr();
	}
};

void init_svc_atts(std::map<std::string, std::string> &svc_atts)
{
	svc_atts["id"] = "";
	svc_atts["svcname"] = "";
	svc_atts["appdir"] = "";
	svc_atts["appname"] = "";
	svc_atts["confext"] = "";
	svc_atts["aliyunkey"] = "";
	svc_atts["upLoopTime"] = "";
	svc_atts["dlllib"] = "";
};

void read_svc_atts(int &id,pyfree::ServiceInfo &svcinfo, std::map<std::string, std::string> svc_atts)
{
	id = atoi(svc_atts["id"].c_str());
	svcinfo .svc_name = svc_atts["svcname"];
	svcinfo.app_dir = svc_atts["appdir"];
	svcinfo.app_name = svc_atts["appname"];
	svcinfo.conf_ext = svc_atts["confext"];
	svcinfo.aliyun_key = svc_atts["aliyunkey"];
	svcinfo.upLoopTime = static_cast<unsigned int>(atoi(svc_atts["upLoopTime"].c_str()));
	if(svcinfo.upLoopTime < 10)
	{
		svcinfo.upLoopTime = 10;
	}
	svcinfo.dll_lib = atoi(svc_atts["dlllib"].c_str()) > 0 ? true : false;

	Print_NOTICE("\nSVCAtts:\nid:%d\nsvc_name:%s\napp_dir:%s\napp_name:%s\nconfext:%s\n"
		"aliyun_key:%s\nuplooptime:%u\ndll_lib:%d\r\n"
		,id
		,svcinfo .svc_name .c_str()
		,svcinfo.app_dir.c_str()
		,svcinfo.app_name.c_str()
		,svcinfo.conf_ext.c_str()
		,svcinfo.aliyun_key.c_str()
		,svcinfo.upLoopTime
		,(int)svcinfo.dll_lib);
};

void pyfree::readSvcMaps(std::map<int,ServiceInfo> &svcmaps, std::string xml_)
{
	try
	{
        acl::string buf;
		if (acl::ifstream::load(xml_.c_str(), &buf) == false)
		{
			Print_WARN("load %s error %s\r\n", xml_.c_str(), acl::last_serror());
			return;
		}

		acl::xml1 xml;
		xml.update(buf);

		acl::xml_node* node 	= &(xml.get_root());
		acl::xml_node* child 	= node->first_child();
        while (child)
		{
			if(0==strcmp(child->tag_name(), "svcconf"))
			{
				acl::xml_node* snode	= child;
				acl::xml_node* schild 	= snode->first_child();
				while (schild)
				{
					if (0==strcmp("SVC",schild->tag_name())) 
					{
						std::map<std::string,std::string> atts_;
						init_svc_atts(atts_);
						getAtt(schild,atts_);
						pyfree::ServiceInfo svc_info;
						int id = 0;
						read_svc_atts(id,svc_info,atts_);
						svcmaps[id] = svc_info;
					}
					schild 	= snode->next_child();
				}
			}
			child = node->next_child();
		}
	}catch (...)
	{
		CLogger::createInstance()->Log(MsgError
			, "read xml file[%s] error: %s %s %d"
			", please check the file format and code!"
			, xml_.c_str()
			, __FILE__, __FUNCTION__, __LINE__);
	}
};
